package cn.itsource.order.service.impl;

import cn.itsource.basic.constant.PayConstants;
import cn.itsource.basic.service.impl.BaseServiceImpl;
import cn.itsource.basic.utils.CodeGenerateUtils;
import cn.itsource.basic.utils.DistanceUtil;
import cn.itsource.order.domain.OrderAddress;
import cn.itsource.order.domain.ProductDetailOrder;
import cn.itsource.order.domain.ProductOrder;
import cn.itsource.order.domain.UserAddress;
import cn.itsource.order.mapper.OrderAddressMapper;
import cn.itsource.order.mapper.ProductDetailOrderMapper;
import cn.itsource.order.mapper.ProductOrderMapper;
import cn.itsource.order.mapper.UserAddressMapper;
import cn.itsource.order.service.IProductOrderService;
import cn.itsource.org.domain.Shop;
import cn.itsource.org.mapper.ShopMapper;
import cn.itsource.pay.domain.PayBill;
import cn.itsource.pay.mapper.PayBillMapper;
import cn.itsource.pay.service.IPayBillService;
import cn.itsource.product.domain.Product;
import cn.itsource.product.domain.ProductDetail;
import cn.itsource.product.mapper.ProductDetailMapper;
import cn.itsource.product.mapper.ProductMapper;
import cn.itsource.quartz.domain.QuartzJobInfo;
import cn.itsource.quartz.service.IQuartzService;
import cn.itsource.user.domain.LoginInfo;
import cn.itsource.user.domain.User;
import cn.itsource.user.mapper.UserMapper;
import org.apache.commons.lang3.time.DateUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.*;


@Service
public class ProductOrderServiceImpl extends BaseServiceImpl<ProductOrder> implements IProductOrderService {

    @Autowired
    private UserAddressMapper userAddressMapper;
    @Autowired
    private UserMapper userMapper;

    @Autowired
    private ShopMapper shopMapper;

    //服务
    @Autowired
    private ProductMapper productMapper;

    //支付单mapper
    @Autowired
    private PayBillMapper payBillMapper;

    //服务订单
    @Autowired
    private ProductOrderMapper productOrderMapper;

    //服务订单明细mapper
    @Autowired
    private ProductDetailOrderMapper productDetailOrderMapper;

    @Autowired
    private OrderAddressMapper orderAddressMapper;


    //支付单service
    @Autowired
    private IPayBillService payBillService;

    @Autowired
    private IQuartzService quartzService;




    @Override
    @Transactional
    public String submitOrder(Map<String, Object> param, LoginInfo loginInfo) {
        //获取用户地址id
        Long addressId = Long.parseLong(param.get("addressId").toString());
        //拿到所有的服务明细
        List<Map<String, Integer>> productDetails = (List<Map<String, Integer>>) param.get("products");
        //获取用户地址对象
        UserAddress userAddress = userAddressMapper.loadById(addressId);
        //根据登录信息id查询user对象
        User user = userMapper.loadByLogininfoid(loginInfo.getId());
        //创建订单地址domain
        OrderAddress orderAddress = createOrderAddress(userAddress, user);
        orderAddressMapper.save(orderAddress);

        //创建服务订单(价格目前还是为空的)
        ProductOrder productOrder = createProductOrder(orderAddress, user);
        productOrderMapper.save(productOrder);
        //服务订单明细
        List<ProductDetailOrder> detailOrders = createProductDetailOrder(productDetails, productOrder);
        //保存服务订单明细
        productDetailOrderMapper.batchSave(detailOrders);
        //根据服务订单明细，修改服务订单的总金额
        productOrderMapper.update(productOrder);

        //获取支付方式
        Integer payType = (Integer) param.get("payType");
        //创建支付单对象
        PayBill payBill = createPayBill(productOrder,payType);
        payBillMapper.save(payBill);
        //添加定时任务
        QuartzJobInfo quartzJobInfo = createOrderTask(productOrder);
        quartzService.addJob(quartzJobInfo);



        //跳转到支付页面
        switch (payType){
            case 1://银联
                break;
            case 2://微信
                break;
            case 3://支付宝
                //写代码跳转到支付宝页面
                return  payBillService.goBuy(productOrder);

        }
        return "";
    }

    /**
     * 添加QuartzJobInfo对象
     * @return
     */
    private QuartzJobInfo createOrderTask(ProductOrder productOrder) {
        QuartzJobInfo quartzJobInfo = new QuartzJobInfo();
        //设置业务类型(定位操作哪张表)
        quartzJobInfo.setType(PayConstants.BUSINESSTYPE_PRODUCT);
        //设置任务名
        quartzJobInfo.setJobName(PayConstants.BUSINESSTYPE_PRODUCT+productOrder.getOrderSn());
        //设置定时时间(Date对象转为cron表达式)
        quartzJobInfo.setFireDate(productOrder.getLastPayTime());

        //任务里面所需要的参数
        Map<String, Object> param = new HashMap<>();
        param.put("orderSn", productOrder.getOrderSn());

        quartzJobInfo.setParams(param);
        return quartzJobInfo;
    }

    /**
     * 创建支付单对象
     * @return
     */
    private PayBill createPayBill(ProductOrder productOrder,Integer payType) {
        PayBill payBill = new PayBill();
        //摘要
        payBill.setDigest("[摘要]服务订单:" +productOrder.getShop().getName()+"提供服务!");
        //交易金额
        payBill.setMoney(productOrder.getPrice());
        //最后支付时间
        payBill.setLastPayTime(productOrder.getLastPayTime());
        //1银联   2 微信  3支付宝
        payBill.setPayChannel(payType);
        //业务类型
        payBill.setBusinessType(PayConstants.BUSINESSTYPE_PRODUCT);
        //业务键
        payBill.setBusinessKey(productOrder.getId());
        //用户
        payBill.setUser(productOrder.getUser());
        //店铺
        payBill.setShop(productOrder.getShop());
        //昵称
        payBill.setNickName(productOrder.getUser().getUsername());
        //设置订单编号
        payBill.setOrderSn(productOrder.getOrderSn());
        return payBill;
    }

    /**
     * 创建服务订单
     *
     * @return
     */
    private ProductOrder createProductOrder(OrderAddress orderAddress, User user) {
        //店铺（分发到最近的门店）
        Shop nearestShop = DistanceUtil.getNearestShop(DistanceUtil.getPoint(orderAddress.getFullAddress()), shopMapper.loadAll());
        ProductOrder order = new ProductOrder();
        //摘要
        order.setDigest(nearestShop.getName() + "门店提供服务!!");
        //订单编号
        order.setOrderSn(orderAddress.getOrderSn());
        //最后支付时间
        order.setLastPayTime(DateUtils.addMinutes(new Date(), 30));
        //用户
        order.setUser(user);
        //设置最近的门店
        order.setShop(nearestShop);
        return order;
    }

    /**
     * 创建服务订单明细
     *
     * @param productDetails
     * @return
     */
    private List<ProductDetailOrder> createProductDetailOrder(List<Map<String, Integer>> productDetails,
                                                              ProductOrder productOrder) {

        //创建一个集合，服务订单明细
        List<ProductDetailOrder> detailOrders = new ArrayList<>();

        //定义一个变量，专门用来装所有明细的金额，算总金额
        BigDecimal totalAmount = new BigDecimal("0");
        for (Map<String, Integer> map : productDetails) {
            //创建服务订单明细对象
            ProductDetailOrder detailOrder = new ProductDetailOrder();
            //设置数量
            detailOrder.setSalecount(map.get("num"));
            //根据服务id获取服务对象
            Product product = productMapper.loadById(Long.parseLong(map.get("id").toString()));
            //设置服务
            detailOrder.setProduct(product);
            //设置服务订单
            detailOrder.setOrder(productOrder);
            //添加服务订单明细
            detailOrders.add(detailOrder);
            //累加金额
            totalAmount = totalAmount.add(
                    product.getSaleprice().multiply(new BigDecimal(map.get("num").toString())
                    ));
        }
        //设置服务订单的总金额
        productOrder.setPrice(totalAmount);
        return detailOrders;
    }

    /**
     * 创建订单地址
     *
     * @param userAddress
     * @return
     */
    private OrderAddress createOrderAddress(UserAddress userAddress, User user) {
        OrderAddress orderAddress = new OrderAddress();
        BeanUtils.copyProperties(userAddress, orderAddress);
        //设置创建时间
        orderAddress.setCreateTime(new Date());
        //设置订单编号
        orderAddress.setOrderSn(CodeGenerateUtils.generateOrderSn(user.getId()));
        return orderAddress;
    }

    public static void main(String[] args) {
        //如果要使用BigDecimal 一定要用字符串创建，否则有问题
        BigDecimal b1 = new BigDecimal("10");
        BigDecimal b2 = new BigDecimal("3");
        System.out.println(b1.divide(b2, 2, BigDecimal.ROUND_HALF_UP));
    }
}
